﻿using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Web;

namespace Sharp.Services.App_Start
{
    public class JwtHelper
    {
        //json web key
        public static JsonWebKey JsonWebKeyRsa256
        {
            get
            {

                //JsonWebKey jwk = new JsonWebKey
                //{
                //    D = "C6EGZYf9U6RI5Z0BBoSlwy_gKumVqRx-dBMuAfPM6KVbwIUuSJKT3ExeL5P0Ky1b4p-j2S3u7Afnvrrj4HgVLnC1ks6rEOc2ne5DYQq8szST9FMutyulcsNUKLOM5cVromALPz3PAqE2OCLChTiQZ5XZ0AiH-KcG-3hKMa-g1MVnGW-SSmm27XQwRtUtFQFfxDuL0E0fyA9O9ZFBV5201ledBaLdDcPBF8cHC53Gm5G6FRX3QVpoewm3yGk28Wze_YvNl8U3hvbxei2Koc_b9wMbFxvHseLQrxvFg_2byE2em8FrxJstxgN7qhMsYcAyw1qGJY-cYX-Ab_1bBCpdcQ",                    
                //    DP = "ErP3OpudePAY3uGFSoF16Sde69PnOra62jDEZGnPx_v3nPNpA5sr-tNc8bQP074yQl5kzSFRjRlstyW0TpBVMP0ocbD8RsN4EKsgJ1jvaSIEoP87OxduGkim49wFA0Qxf_NyrcYUnz6XSidY3lC_pF4JDJXg5bP_x0MUkQCTtQE",
                //    DQ = "YbBsthPt15Pshb8rN8omyfy9D7-m4AGcKzqPERWuX8bORNyhQ5M8JtdXcu8UmTez0j188cNMJgkiN07nYLIzNT3Wg822nhtJaoKVwZWnS2ipoFlgrBgmQiKcGU43lfB5e3qVVYUebYY0zRGBM1Fzetd6Yertl5Ae2g2CakQAcPs",
                //    E = "AQAB",
                //    QI = "lbljWyVY-DD_Zuii2ifAz0jrHTMvN-YS9l_zyYyA_Scnalw23fQf5WIcZibxJJll5H0kNTIk8SCxyPzNShKGKjgpyZHsJBKgL3iAgmnwk6k8zrb_lqa0sd1QWSB-Rqiw7AqVqvNUdnIqhm-v3R8tYrxzAqkUsGcFbQYj4M5_F_4",
                //    N = "6-FrFkt_TByQ_L5d7or-9PVAowpswxUe3dJeYFTY0Lgq7zKI5OQ5RnSrI0T9yrfnRzE9oOdd4zmVj9txVLI-yySvinAu3yQDQou2Ga42ML_-K4Jrd5clMUPRGMbXdV5Rl9zzB0s2JoZJedua5dwoQw0GkS5Z8YAXBEzULrup06fnB5n6x5r2y1C_8Ebp5cyE4Bjs7W68rUlyIlx1lzYvakxSnhUxSsjx7u_mIdywyGfgiT3tw0FsWvki_KYurAPR1BSMXhCzzZTkMWKE8IaLkhauw5MdxojxyBVuNY-J_elq-HgJ_dZK6g7vMNvXz2_vT-SykIkzwiD9eSI9UWfsjw",                    
                //    P = "_avCCyuo7hHlqu9Ec6R47ub_Ul_zNiS-xvkkuYwW-4lNnI66A5zMm_BOQVMnaCkBua1OmOgx7e63-jHFvG5lyrhyYEmkA2CS3kMCrI-dx0fvNMLEXInPxd4np_7GUd1_XzPZEkPxBhqf09kqryHMj_uf7UtPcrJNvFY-GNrzlJk",
                //    Q = "7gvYRkpqM-SC883KImmy66eLiUrGE6G6_7Y8BS9oD4HhXcZ4rW6JJKuBzm7FlnsVhVGro9M-QQ_GSLaDoxOPQfHQq62ERt-y_lCzSsMeWHbqOMci_pbtvJknpMv4ifsQXKJ4Lnk_AlGr-5r5JR5rUHgPFzCk9dJt69ff3QhzG2c",
                //    Kty = JsonWebAlgorithmsKeyTypes.RSA,
                //    Kid = "RsaSecurityKey_2048"
                //};

                // 使用此方法生成 jsonwebkey 保存成常量
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
                string xmlRsa = rsa.ToXmlString(true);
                JsonWebKey jwk = JsonWebKeyConverter.ConvertFromRSASecurityKey(new RsaSecurityKey(rsa));

                return jwk;
            }
        }


        private static SigningCredentials _credentials;
        private static SigningCredentials Credentials
        {
            get
            {
                if (_credentials == null)
                {
                    _credentials = new SigningCredentials(JsonWebKeyRsa256, SecurityAlgorithms.RsaSha256, SecurityAlgorithms.Sha256);
                }

                return _credentials;
            }
        }

        /// <summary>
        /// DateTime as UTV for UnixEpoch
        /// </summary>
        public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

        // 传递的日期需要使用此方法转换成long 此方法从源码中复制出来的
        public static long GetIntDate(DateTime datetime)
        {
            DateTime dateTimeUtc = datetime;
            if (datetime.Kind != DateTimeKind.Utc)
            {
                dateTimeUtc = datetime.ToUniversalTime();
            }

            if (dateTimeUtc.ToUniversalTime() <= UnixEpoch)
            {
                return 0;
            }

            return (long)(dateTimeUtc - UnixEpoch).TotalSeconds;
        }

        // 创建token
        public static string CreateToken()
        {
            var tokenHandler = new JsonWebTokenHandler();
            var payload = new JObject()
            {
                { "phone","13211212112"},
                { JwtRegisteredClaimNames.Email, "Bob@contoso.com"},
                { JwtRegisteredClaimNames.GivenName, "Bob"},
                { JwtRegisteredClaimNames.Iss, "issuer" },
                { JwtRegisteredClaimNames.Aud, "audience" },
                 { JwtRegisteredClaimNames.Nbf,  GetIntDate(DateTime.Now)}, // 何时生效
                { JwtRegisteredClaimNames.Exp,GetIntDate(DateTime.Now.AddSeconds(30000))} // 何时到期

            };


            var accessToken = tokenHandler.CreateToken(payload.ToString(), Credentials);
            return accessToken;
        }

        // 验证token
        public static bool ValidateToken(string accessToken = "")
        {
            try
            {
                var tokenHandler = new JsonWebTokenHandler();
                var tokenValidationParameters = new TokenValidationParameters()
                {
                    ValidAudience = "audience",
                    ValidIssuer = "issuer",
                    IssuerSigningKey = Credentials.Key,
                    ValidateLifetime = true,
                    ValidateAudience = true,
                    ValidateIssuer = true
                };

                var tokenValidationResult = tokenHandler.ValidateToken(accessToken, tokenValidationParameters);
                var jsonWebToken = tokenValidationResult.SecurityToken as JsonWebToken;
                //var email = jsonWebToken.Payload.Value<string>(JwtRegisteredClaimNames.Email);
                var email = "";
                // Retrieving a claim value that isn’t provided as a JsonWebToken property
                if (!email.Equals("Bob@contoso.com"))
                {
                    //throw new SecurityTokenException("Token does not contain the correct value for the 'email' claim.");
                    return false;
                }
            }
            catch (Exception ex)
            {
                // 有效期，签名，issuer验证不通过都会异常
                return false;
            }
            return true;
        }
    }
}